#!/usr/bin/env python3
"""
GitCode平台界面模块
包含GitCode平台的所有界面逻辑和数据处理功能
"""

import os
import random
from typing import List, Dict, Tuple

import pandas as pd
import plotly.express as px
import streamlit as st
from loguru import logger

from .commits_analyzer import GitCodeCommitsAnalyzer
from .repos_fetcher import GitCodeReposFetcher


class GitCodeInterface:
    """GitCode平台界面管理类"""

    def __init__(self):
        self.platform_name = "GitCode"

    def get_random_token(self) -> str:
        """从环境变量中获取随机GitCode访问令牌"""
        token_str = os.getenv('GITCODE_ACCESS_TOKEN', '')
        if not token_str:
            return ''
        tokens = [token.strip() for token in token_str.split(',') if token.strip()]
        if not tokens:
            return ''
        return random.choice(tokens)

    def render_sidebar_config(self) -> Tuple[str, str]:
        """渲染GitCode侧边栏配置
        
        Returns:
            Tuple[access_token, org_name]: 访问令牌和组织名称
        """
        st.sidebar.subheader("🔧 GitCode 配置")

        # Token配置
        env_token = self.get_random_token()
        if env_token:
            st.sidebar.success(f"✅ 已从环境变量随机选择GitCode Token（前8位: {env_token[:8]}...)")
        else:
            st.sidebar.info("ℹ️ 未检测到GitCode环境变量，请手动输入Access Token")

        access_token = st.sidebar.text_input(
            "GitCode Access Token",
            value=env_token,
            type="password",
            help="GitCode API访问令牌",
            key="platforms_gitcode_access_token"
        )

        org_name = st.sidebar.text_input(
            "组织名称",
            value="dlut-water",
            help="要分析的GitCode组织名称",
            key="platforms_gitcode_org_name"
        )

        return access_token, org_name

    def fetch_repositories(self, access_token: str, org_name: str) -> pd.DataFrame:
        """获取GitCode仓库列表"""
        try:
            fetcher = GitCodeReposFetcher(access_token)
            with st.spinner(f"正在获取GitCode组织 '{org_name}' 的仓库列表..."):
                df = fetcher.get_all_repos_dataframe(org_name)
            return df
        except Exception as e:
            logger.error(f"获取GitCode仓库列表失败: {e}")
            raise e

    def fetch_commits(self, access_token: str, owner: str, repo: str, since_date: str = None) -> pd.DataFrame:
        """获取GitCode提交记录"""
        try:
            analyzer = GitCodeCommitsAnalyzer(access_token)
            with st.spinner(f"正在获取GitCode仓库 '{owner}/{repo}' 的提交记录..."):
                kwargs = {}
                if since_date:
                    kwargs['since'] = since_date
                commits = analyzer.get_all_commits(owner, repo, **kwargs)
                df = analyzer.commits_to_dataframe(commits)
            return df
        except Exception as e:
            logger.error(f"获取GitCode提交记录失败: {e}")
            raise e

    def fetch_overall_analysis(self, access_token: str, org_name: str, repos_df: pd.DataFrame, since_date: str) -> List[
        pd.DataFrame]:
        """获取GitCode所有仓库的整体分析数据"""
        try:
            analyzer = GitCodeCommitsAnalyzer(access_token)
            overall_data = []

            # 移除UI显示逻辑，由UI层处理
            for idx, repo in repos_df.iterrows():
                repo_name = repo['name']

                try:
                    kwargs = {}
                    if since_date:
                        kwargs['since'] = since_date

                    commits = analyzer.get_all_commits(org_name, repo_name, **kwargs)
                    if commits:
                        df = analyzer.commits_to_dataframe(commits)
                        if not df.empty:
                            df['repo_name'] = repo_name
                            overall_data.append(df)

                except Exception as e:
                    logger.error(f"分析GitCode仓库 {repo_name} 失败: {e}")
                    continue
            return overall_data

        except Exception as e:
            logger.error(f"GitCode整体分析失败: {e}")
            raise e

    def fetch_student_analysis(self, access_token: str, org_name: str, repos_df: pd.DataFrame, since_date: str,
                               progress_callback=None) -> List[
        Dict]:
        """获取GitCode提交者级别的详细分析数据"""
        try:
            analyzer = GitCodeCommitsAnalyzer(access_token)
            repo_names = repos_df['name'].tolist()

            # UI显示逻辑已移至UI层处理

            # 移除UI显示逻辑，由UI层处理
            kwargs = {}
            if since_date:
                kwargs['since'] = since_date

            student_stats = analyzer.get_student_level_statistics(
                org_name, repo_names, progress_callback=progress_callback, **kwargs
            )
            return student_stats

        except Exception as e:
            logger.error(f"GitCode提交者分析失败: {e}")
            raise e

    def display_repo_overview(self, df: pd.DataFrame):
        """显示GitCode仓库概览"""
        if df.empty:
            st.warning("没有GitCode仓库数据可显示")
            return

        st.subheader("📊 GitCode仓库概览")

        # 统计指标
        col1, col2, col3, col4 = st.columns(4)

        with col1:
            st.metric("总仓库数", len(df))

        with col2:
            private_count = df['private'].sum() if 'private' in df.columns else 0
            st.metric("私有仓库", private_count)

        with col3:
            fork_count = df['fork'].sum() if 'fork' in df.columns else 0
            st.metric("Fork仓库", fork_count)

        with col4:
            total_stars = df['stargazers_count'].sum() if 'stargazers_count' in df.columns else 0
            st.metric("总Star数", total_stars)

        # 编程语言分布
        if 'language' in df.columns:
            st.subheader("💻 编程语言分布")
            language_counts = df['language'].value_counts().head(10)

            if not language_counts.empty:
                fig = px.pie(
                    values=language_counts.values,
                    names=language_counts.index,
                    title="Top 10 编程语言分布"
                )
                st.plotly_chart(fig, use_container_width=True)

        # 仓库列表
        st.subheader("📋 GitCode仓库列表")
        display_columns = ['name', 'description', 'language', 'stargazers_count', 'forks_count', 'updated_at']
        available_columns = [col for col in display_columns if col in df.columns]

        if available_columns:
            st.dataframe(
                df[available_columns].head(20),
                use_container_width=True,
                hide_index=True
            )

    def display_commits_analysis(self, df: pd.DataFrame, repo_name: str):
        """显示GitCode提交分析"""
        if df.empty:
            st.warning("没有GitCode提交数据可显示")
            return

        st.subheader(f"📈 GitCode {repo_name} 提交分析")

        # 调试信息：显示原始数据结构
        with st.expander("🔍 调试信息 - 原始数据结构", expanded=False):
            st.write("**DataFrame列信息:**")
            st.json({
                "columns": list(df.columns),
                "shape": df.shape,
                "dtypes": {col: str(dtype) for col, dtype in df.dtypes.items()}
            })

            if len(df) > 0:
                st.write("**前3条记录样本:**")
                sample_data = df.head(3).to_dict('records')
                st.json(sample_data)

                st.write("**作者字段统计:**")
                author_stats = {
                    "unique_author_names": df['author_name'].nunique() if 'author_name' in df.columns else 0,
                    "empty_author_names": (df['author_name'] == '').sum() if 'author_name' in df.columns else 0,
                    "null_author_names": df['author_name'].isnull().sum() if 'author_name' in df.columns else 0,
                    "sample_author_names": df['author_name'].dropna().unique()[
                                           :10].tolist() if 'author_name' in df.columns else []
                }
                st.json(author_stats)

        # 基本统计
        col1, col2, col3, col4 = st.columns(4)

        with col1:
            st.metric("总提交数", len(df))

        with col2:
            unique_authors = df['author_name'].nunique() if 'author_name' in df.columns else 0
            st.metric("贡献者数量", unique_authors)

        with col3:
            if 'author_date' in df.columns:
                date_range = (df['author_date'].max() - df['author_date'].min()).days
                st.metric("时间跨度(天)", date_range)
            else:
                st.metric("时间跨度(天)", "N/A")

        with col4:
            total_changes = df['total_changes'].sum() if 'total_changes' in df.columns else 0
            st.metric("总代码变更", f"{total_changes:,}")

        # 创建图表
        self._create_commit_charts(df)

    def _create_commit_charts(self, df: pd.DataFrame):
        """创建GitCode提交分析图表"""
        if df.empty:
            return

        # 1. 贡献者统计
        if 'author_name' in df.columns:
            st.subheader("👥 Top GitCode贡献者")
            top_contributors = df['author_name'].value_counts().head(10)

            fig = px.bar(
                x=top_contributors.values,
                y=top_contributors.index,
                orientation='h',
                title="Top 10 GitCode贡献者提交统计",
                labels={'x': '提交次数', 'y': '贡献者'}
            )
            fig.update_layout(height=400)
            st.plotly_chart(fig, use_container_width=True)

        # 2. 时间分布分析
        if 'author_date' in df.columns:
            col1, col2 = st.columns(2)

            with col1:
                # 每小时提交分布
                if 'hour' in df.columns:
                    st.subheader("🕐 每小时提交分布")
                    hourly_commits = df['hour'].value_counts().sort_index()

                    fig = px.line(
                        x=hourly_commits.index,
                        y=hourly_commits.values,
                        title="每小时提交分布",
                        labels={'x': '小时', 'y': '提交次数'}
                    )
                    fig.update_traces(mode='lines+markers')
                    st.plotly_chart(fig, use_container_width=True)

            with col2:
                # 每周提交分布
                if 'weekday' in df.columns:
                    st.subheader("📅 每周提交分布")
                    weekday_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
                    weekday_commits = df['weekday'].value_counts().reindex(weekday_order, fill_value=0)

                    fig = px.bar(
                        x=weekday_order,
                        y=weekday_commits.values,
                        title="每周提交分布",
                        labels={'x': '星期', 'y': '提交次数'}
                    )
                    st.plotly_chart(fig, use_container_width=True)

        # 3. 月度趋势
        if 'author_date' in df.columns:
            st.subheader("📈 月度提交趋势")
            monthly_commits = df.groupby(df['author_date'].dt.to_period('M')).size()

            if not monthly_commits.empty:
                fig = px.line(
                    x=[str(period) for period in monthly_commits.index],
                    y=monthly_commits.values,
                    title="月度提交趋势",
                    labels={'x': '月份', 'y': '提交次数'}
                )
                fig.update_traces(mode='lines+markers')
                st.plotly_chart(fig, use_container_width=True)

        # 4. 代码变更分析
        if 'total_changes' in df.columns and 'author_name' in df.columns:
            st.subheader("💻 代码变更分析")
            author_changes = df.groupby('author_name')['total_changes'].sum().sort_values(ascending=False).head(10)

            if not author_changes.empty:
                fig = px.bar(
                    x=author_changes.index,
                    y=author_changes.values,
                    title="Top 10 GitCode贡献者代码变更量",
                    labels={'x': '贡献者', 'y': '代码变更行数'}
                )
                fig.update_layout(xaxis_tickangle=-45)
                st.plotly_chart(fig, use_container_width=True)

    def validate_config(self, access_token: str, org_name: str) -> bool:
        """验证GitCode配置"""
        if not access_token:
            st.error("请填写GitCode Access Token")
            return False
        if not org_name:
            st.error("请填写GitCode组织名称")
            return False
        return True
